home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-12-02 | 6.6 KB | 286 lines | [TEXT/CWIE] |
- /*
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
- */
-
- #include "ScriptableStuffItEngine.h" // app
- #include "Search.h" // MoreFiles
- #include "MoreFilesExtras.h" // MoreFiles
-
- #include <AppleEvents.h>
- #include <Files.h>
- #include <Errors.h>
- #include <PLStringFuncs.h>
- #include <TextUtils.h>
-
- enum
- {
- eDontCareAboutName = 0x0000,
- eNameBeginsWith = 0x0001,
- eNameIs = 0x0002,
- eNameContains = 0x0004,
- eNameEndsWith = 0x0008
- };
-
- typedef struct
- {
- UInt16 caresAboutName;
- OSType fdType;
- FSSpec toSearch;
- CSParam csParam;
- CInfoPBRec searchInfo1;
- CInfoPBRec searchInfo2;
- Str31 nameBuffer;
- FSSpec matches [ ];
- }
- tFindFilesDataBlock, *tFindFilesDataBlockP;
-
- static pascal OSErr MyMemError (void)
- {
- OSErr err = MemError ( );
- // if (err == -113) Debugger ( );
- return err;
- }
-
- static pascal OSErr FinishFindFilesSetUp (const AppleEvent *event, tFindFilesDataBlock &ffdb)
- {
- OSErr err = noErr;
-
- UInt8 *param = nil;
-
- ffdb.caresAboutName = eDontCareAboutName;
-
- if (!(err = GetOptionalTextParameter (event,keyNameBeginsWith,¶m)))
- {
- ffdb.caresAboutName |= eNameBeginsWith;
- }
-
- if (!err && param)
- {
- Size size = GetPtrSize (Ptr (param));
-
- if (!(err = MyMemError ( )))
- {
- if (size > 31)
- err = paramErr;
- else
- {
- ffdb.csParam.ioSearchBits |= fsSBPartialName;
- BlockMoveData (param, 1 + ffdb.nameBuffer, size);
- ffdb.nameBuffer [0] = size;
- ffdb.csParam.ioSearchInfo1->hFileInfo.ioNamePtr = ffdb.nameBuffer;
- }
- }
-
- DisposePtr (Ptr (param));
- if (!err) err = MyMemError ( );
- param = nil;
- }
-
- if (!err && !(err = GetOptionalTextParameter (event,keyFileTypeIs,¶m)))
- {
- if (param)
- {
- Size size = GetPtrSize (Ptr (param));
-
- if (!(err = MyMemError ( )))
- {
- if (size != sizeof (ffdb.fdType))
- err = paramErr;
- else
- {
- ffdb.searchInfo2.hFileInfo.ioFlAttrib |= ioDirMask; // we care whether it is a dir
-
- BlockMoveData (param, &(ffdb.fdType), size);
-
- if ('fold' == ffdb.fdType || 'ƒldr' == ffdb.fdType) // magic file types for directories
- ffdb.searchInfo1.hFileInfo.ioFlAttrib |= ioDirMask; // it must be a dir
- else
- {
- ffdb.csParam.ioSearchBits |= fsSBFlFndrInfo;
- ffdb.csParam.ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = ffdb.fdType;
- ffdb.csParam.ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF;
- }
- }
- }
- }
-
- DisposePtr (Ptr (param));
- if (!err) err = MyMemError ( );
- param = nil;
- }
-
- return err;
- }
-
- static pascal OSErr AddHitsToReply (AEDescList *replyList, tFindFilesDataBlock &ffdb)
- {
- OSErr err = noErr;
-
- if (long index = ffdb.csParam.ioActMatchCount)
- {
- FSSpecPtr scan = ffdb.matches + index - 1;
-
- do
- {
- Boolean addThisItem = true;
-
- if (eNameBeginsWith & ffdb.caresAboutName)
- {
- if (scan->name [0] < *(ffdb.nameBuffer))
- addThisItem = false;
- else if (scan->name [0] > 31)
- {
- err = paramErr;
- break;
- }
- else
- {
- Str31 victim;
- PLstrcpy (victim,scan->name);
- victim [0] = *(ffdb.nameBuffer);
- if (!EqualString (victim, ffdb.nameBuffer, false, true))
- addThisItem = false;
- }
- }
-
- if (addThisItem)
- {
- Size dataSize = sizeof (*scan) - sizeof (scan->name) + *(scan->name) + 1;
- err = AEPutPtr (replyList, 0, typeFSS, scan, dataSize);
- if (err) break;
- }
- }
- while (--scan, --index);
- }
-
- return err;
- }
-
- pascal OSErr FindFiles (const AppleEvent *event, AppleEvent *reply)
- {
- OSErr err = noErr;
-
- if (reply->dataHandle)
- {
- PurgeMem (maxSize);
- err = MyMemError ( );
-
- if (!err || err == memFullErr)
- {
- //
- // Allocate 2/5 of available memory, leaving a 48K cushion.
- //
-
- Size blockSize = CompactMem (maxSize);
- err = MyMemError ( );
-
- if (!err)
- {
- blockSize -= 1024L * 48L;
- blockSize *= 2;
- blockSize /= 5;
-
- long ioReqMatchCount = (blockSize - sizeof (tFindFilesDataBlock)) / sizeof (FSSpec);
-
- if (ioReqMatchCount < 1)
- err = memFullErr;
- else
- {
- if (ioReqMatchCount > 10)
- ioReqMatchCount = 10;
-
- blockSize = (ioReqMatchCount * sizeof (FSSpec)) + sizeof (tFindFilesDataBlock);
-
- tFindFilesDataBlockP blockP = tFindFilesDataBlockP (::NewPtrClear (blockSize));
-
- if (!blockP)
- err = MyMemError ( );
- else
- {
- DescType actualType;
- Size actualSize = sizeof (blockP->toSearch);
-
- if (!(err = ::AEGetParamPtr (event,keySearchTarget,typeFSS,&actualType,&(blockP->toSearch),actualSize,&actualSize)))
- {
- blockP->csParam.ioVRefNum = blockP->toSearch.vRefNum;
- blockP->csParam.ioMatchPtr = blockP->matches;
- blockP->csParam.ioReqMatchCount = ioReqMatchCount;
- blockP->csParam.ioSearchInfo1 = &(blockP->searchInfo1);
- blockP->csParam.ioSearchInfo2 = &(blockP->searchInfo2);
- blockP->csParam.ioSearchBits = fsSBFlAttrib;
-
- long dirID;
- Boolean isDir;
-
- if (blockP->toSearch.parID != fsRtParID)
- err = ::FSpGetDirectoryID (&(blockP->toSearch), &dirID, &isDir);
- else
- {
- dirID = fsRtDirID;
- isDir = true;
- }
-
- if (!err)
- {
- if (!isDir)
- err = afpObjectTypeErr;
- else if (!(err = ::FinishFindFilesSetUp (event, *blockP)))
- {
- OSErr err2 = noErr;
-
- AEDescList descList;
-
- if (!(err = ::AECreateList (nil, 0, false, &descList)))
- {
- Boolean done = false;
-
- do
- {
- if (dirID == fsRtDirID)
- err = ::PBCatSearchSync (&(blockP->csParam));
- else
- err = ::IndexedSearch (&(blockP->csParam), dirID);
-
- if (err == eofErr)
- {
- done = true;
- err = noErr;
- }
-
- if (!err && blockP->csParam.ioActMatchCount)
- {
- err = ::AddHitsToReply (&descList,*blockP);
- EventRecord dummyEvent;
- (void) WaitNextEvent (0,&dummyEvent,10,nil);
- }
- }
- while (!done);
-
- if (!err)
- {
- err = ::AEPutParamDesc (reply,keyDirectObject,&descList);
- }
-
- err2 = ::AEDisposeDesc (&descList);
- if (!err) err = err2;
- }
- }
- }
- }
- ::DisposePtr (Ptr (blockP));
- if (!err) err = MyMemError ( );
- }
- }
- }
- }
- }
-
- return err;
- }
-